package com.yc.fav.demo;

import com.mysql.jdbc.AssertionFailedException;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class Junit {

    private int well;
    private int error;
    private int failure;

    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        Junit junit = new Junit();
        Test1 t = new Test1();
        junit.test(t);
    }

    public void test(Object tester) throws InvocationTargetException, IllegalAccessException {
        // 1.定义Before 和 After 注解
        // 2.执行所有的被测试方法
        // 3.统计测试结果
        //      1) 正常执行完成  ==> 正确 OK
        //      2) 如果出现异常  ==> 错误 error
        //      3) 断言错误     ==>  失败 failure
        // 获取该类定义的所有方法
        Method[] decclaredMethods = tester.getClass().getDeclaredMethods();
        // 所有被测试的方法集合
        List<Method> testMethods = new ArrayList<>();
        List<Method> beforeMethods = new ArrayList<>();
        List<Method> afterMethods = new ArrayList<>();
        for (Method method : decclaredMethods){
            if (method.getAnnotation(Before.class) != null){
                beforeMethods.add(method);
            }
            if (method.getAnnotation(Test.class) != null){
                testMethods.add(method);
            }
            if (method.getAnnotation(After.class) != null){
                afterMethods.add(method);
            }
        }
        System.out.println(beforeMethods);
        System.out.println(testMethods);
        System.out.println(afterMethods);
        System.out.println("==========================");



        for(Method test : testMethods){
            for(Method before : beforeMethods){
                before.invoke(tester);
            }
            try {
                test.invoke(tester);
            }catch ( InvocationTargetException e){
                Throwable ie = e.getCause();
                if (ie instanceof AssertionError){
                    failure ++;
                }
                if (ie instanceof Exception){
                    error ++;
                }
                well ++;
            } finally {
                for(Method after : afterMethods){
                    after.invoke(tester);
                }
            }
        }
        System.out.println("well  " + well);
        System.out.println("error  " + error);
        System.out.println("failure  " + failure);
    }
}

class Test1{

    @Before
    public void before1(){
        System.out.println("每一个测试方法执行前，执行的方法 before1");
    }

    @Before
    public void before2(){
        System.out.println("每一个测试方法执行前，执行的方法 before2");
    }

    @After
    public void after(){
        System.out.println("每一个测试方法执行后，执行的方法 after");
    }

    @Test
    public void test1(){
        System.out.println("测试方法1");
    }

    @Test
    public void test2(){
        System.out.println("测试方法2");
        int i = 1/0;
    }

    @Test
    public void test3(){
        System.out.println("测试方法3");
        throw new AssertionError("断言错误");
    }

    public void test4(){
        System.out.println("不是测试方法");
    }
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test{

}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Before{

}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface After{

}
